#include <mesh/transform.h>
#include <mesh/mesh.h>
#include <app/ameTypes.h>

#include <glm/glm.hpp>
#include <glm/gtx/transform.hpp>

Transform::Transform ( glm::vec3 position, glm::vec3 rotation, glm::vec3 scale ) {
    
    this -> position = position;
    this -> rotation = rotation;
    this -> scale = scale;
}

Transform::Transform () {
    
    position = glm::vec3 (0, 0, 0);
    rotation = glm::vec3 (0, 0, 0);
    scale = glm::vec3 (1, 1, 1);
}


void Transform::setX ( double x ) {
    position.x = x;
}

void Transform::setY ( double y ) {
    position.y = y;
}

void Transform::setZ ( double z ) {
    position.z = z;
}


glm::vec3 Transform::getLocation () {
    return this -> position;
}

glm::vec3 Transform::getRotation () {
    return this -> rotation;
}

glm::vec3 Transform::getScale () {
    return this -> scale;
}



void Transform::setPosition ( glm::vec3 axis ) {
    position.x = axis.x;
    position.y = axis.y;
    position.z = axis.z;
}

void Transform::translate ( glm::vec3 direction ) {
    position.x += direction.x;
    position.y += direction.y;
    position.z += direction.z;
}


void Transform::setRotation ( glm::vec3 deg ) {
    rotation = deg;
}
void Transform::rotate ( glm::vec3 deg ) {
    rotation.x += deg.x;
    rotation.y += deg.y;
    rotation.z += deg.z;
}


void Transform::setScale ( glm::vec3 scale ) {
    this -> scale = scale;
}


glm::mat4 Transform::getModel () {
    
    glm::mat4 positionMatrix = glm::translate ( this -> position );
    
    glm::mat4 scaleMatrix = glm::scale ( this -> scale );
    
    glm::mat4 rotationX = glm::rotate ( this -> rotation.x, glm::vec3 ( 1.0, 0.0, 0.0 ) );
    glm::mat4 rotationY = glm::rotate ( this -> rotation.y, glm::vec3 ( 0.0, 1.0, 0.0 ) );
    glm::mat4 rotationZ = glm::rotate ( this -> position.z, glm::vec3 ( 0.0, 0.0, 1.0 ) );
    
    glm::mat4 rotationMatrix = rotationX * rotationY * rotationZ;
    
    return positionMatrix * rotationMatrix * scaleMatrix;
}

glm::mat4 Transform::GetMatrixViewProjection ( Camera& camera ) {
    
    glm::mat4 viewProjection = camera.getViewProjection ();
    glm::mat4 model = getModel ();
    
    return viewProjection * model;
}
